home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Digital Signatures / Digital Signature Demo / Source ƒ / SIGStatusManager.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-11  |  7.4 KB  |  303 lines  |  [TEXT/KAHL]

  1. /*
  2.  * SIGStatusWindow.c
  3.  * Copyright © 1993 Apple Computer Inc.
  4.  * All Rights Reserved
  5.  *
  6.  * Manage a status window that can be used to stop Digital Signature
  7.  * operation. It is created when an application passes gSIGStatusProc
  8.  * to one of the signing or verifying methods. It creates a small status
  9.  * window with a "barber pole" progress indicator and a Cancel button.
  10.  *
  11.  * While a production application would define this window and its contents
  12.  * using resources, I chose to use compiled-in values and strings to
  13.  * keep all the information in one place.
  14.  *
  15.  * Note that it is rather Think C Class Library specific. In particular,
  16.  * if you use this, you must create any windows with signable data using
  17.  * TCL methods. In particular, you cannot "sign" from a Modal Dialog.
  18.  * DemoSignedObjectDialog shows how a Modal Dialog may be implemented using
  19.  * TCL classes.
  20.  */
  21. #include "SIGStatusManager.h"
  22. #include <CApplication.h>
  23. #include <CBartender.h>
  24. #include <CDecorator.h>
  25. #include <CEditText.h>
  26. #include <CPane.h>
  27. #include <CButton.h>
  28. #include <CDesktop.h>
  29. #include <Commands.h>
  30. #include <CWindow.h>
  31. extern CApplication        *gApplication;
  32. extern CBartender        *gBartender;
  33. extern CDesktop            *gDesktop;
  34. extern CDecorator        *gDecorator;
  35. static Boolean            gContinueSigning;    /* False stops signing    */
  36. pascal Boolean            gSIGStatusProc(void);
  37.  
  38. /*
  39.  * The following variables are needed by the status procedure.
  40.  */
  41. #define kStatusUpdateWait        (1)            /* Update frequency        */
  42. typedef struct PatternStruct {
  43.     Pattern            aPattern;
  44. } PatternStruct;
  45.  
  46. static PatternStruct    gBarberPolePattern = {
  47.     { 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE1, 0xC3, 0x87 }
  48. };
  49.  
  50. /*
  51.  *** Here are some classes that are used only by SIGStatusManager.
  52.  */
  53. /*
  54.  * This pane displays the "barber pole" progress info.
  55.  */
  56. struct ProgressPane : CPane {
  57. private:
  58.         PatternStruct            itsPattern;
  59. public:
  60.         void                    IProgressPane(
  61.             CWindow                    *theWindow
  62.         );
  63.         void                    Draw(
  64.             Rect                    *aRect
  65.         );
  66. };
  67.  
  68. /*
  69.  * SIGStatusManager displays this window.
  70.  */
  71. struct SIGStatusWindow : CWindow {
  72. public:
  73.         ProgressPane            *itsProgressPane;
  74.         
  75. public:
  76.         /*
  77.          * Create the status window.
  78.          */
  79.         void                    ISIGStatusWindow(
  80.             CDirector                *aSupervisor,
  81.             ConstStr255Param        actionString,
  82.             ConstStr255Param        objectString
  83.         );
  84. };
  85.  
  86. /*
  87.  * Initialize a status manager window.
  88.  */
  89. void
  90. SIGStatusManager::ISIGStatusManager(
  91.         ConstStr255Param    actionString,
  92.         ConstStr255Param    objectString
  93.     )
  94. {
  95.         inherited::IDirector((CDirector *) gApplication);
  96.         itsWindow = (CWindow *) new (SIGStatusWindow);
  97.         ((SIGStatusWindow *) itsWindow)->ISIGStatusWindow(
  98.             this,
  99.             actionString,
  100.             objectString
  101.         );
  102.         BecomeGopher(TRUE);
  103.         itsTickCount = TickCount() + kStatusUpdateWait;
  104.         gContinueSigning = TRUE;
  105. }
  106.  
  107. void
  108. SIGStatusManager::DoCommand(
  109.         long                    theCommand
  110.     )
  111. {
  112.         switch (theCommand) {
  113.         case cmdCancel:
  114.             gContinueSigning = FALSE;
  115.             /* Let our supervisors see cmdCancel, too    */
  116.         default:
  117.             inherited::DoCommand(theCommand);
  118.             break;
  119.         }
  120. }
  121.  
  122. /*
  123.  * Dawdle is called by the idle loop.
  124.  * We draw the window directly to avoid
  125.  * the overhead of an update event.
  126.  */
  127. void
  128. SIGStatusManager::Dawdle(
  129.         long                *maxSleep
  130.     )
  131. {
  132.         unsigned long        now;
  133.         
  134.         now = TickCount();
  135.         if (now >= itsTickCount) {
  136.             ((SIGStatusWindow *) itsWindow)
  137.                 ->itsProgressPane
  138.                 ->Prepare();
  139.             ((SIGStatusWindow *) itsWindow)
  140.                 ->itsProgressPane
  141.                 ->Draw(NULL);
  142.             itsTickCount += kStatusUpdateWait;
  143.         }
  144.         *maxSleep = itsTickCount - now;
  145. }
  146.  
  147. /*
  148.  * Create a status window.
  149.  */
  150. void
  151. SIGStatusWindow::ISIGStatusWindow(
  152.         CDirector                *aSupervisor,
  153.         ConstStr255Param        actionString,
  154.         ConstStr255Param        objectString
  155.     )
  156. {
  157.         Rect                bounds;
  158.         CButton                *aCancelButton;
  159.         CEditText            *someText;
  160.         
  161.         SetRect(&bounds, 40, 40, 360, 130);
  162.         inherited::INewWindow(
  163.             &bounds,                        /* Bounds rect            */
  164.             FALSE,                            /* Initially invisible    */
  165.             movableDBoxProc,                /* Moveable modal dlog    */
  166.             FALSE,                            /* Floating window        */
  167.             FALSE,                            /* No goAway box        */
  168.             gDesktop,                        /* Enclosure            */
  169.             aSupervisor                        /* Supervisor            */
  170.         );
  171.         SetWantsClicks(TRUE);
  172.         /*
  173.          * Create the window contents. There are three subpanes:
  174.          * a Cancel button, progress "barber pole", and a
  175.          * TextEdit window with the two strings.
  176.          */
  177.         aCancelButton = new (CButton);
  178.         aCancelButton->INewButton(
  179.             60,                                /* Width                */
  180.             20,                                /* Height                */
  181.             250,                            /* Horizontal position    */
  182.             60,                                /* Vertical position    */
  183.             "\pCancel",                        /* Text                    */
  184.             TRUE,                            /* Visible                */
  185.             pushButProc,                    /* It's a button        */
  186.             this,                            /* Enclosure            */
  187.             this                            /* Supervisor            */
  188.         );
  189.         aCancelButton->SetClickCmd(cmdCancel);
  190.         /* */
  191.         itsProgressPane = new (ProgressPane);
  192.         itsProgressPane->IProgressPane(this);
  193.         /* */
  194.         someText = new (CEditText);
  195.         someText->IEditText(
  196.             this,                            /* Enclosure            */
  197.             this,                            /* Supervisor            */
  198.             300,                            /* Width                */
  199.             40,                                /* Height                */
  200.             10,                                /* Horizontal position    */
  201.             10,                                /* Vertical position    */
  202.             sizFIXEDLEFT,                    /* Fixed position        */
  203.             sizFIXEDTOP,                    /* Fixed position        */
  204.             300                                /* Line width            */
  205.         );
  206.         someText->Specify(FALSE, FALSE, FALSE);    /* Can't touch        */
  207.         someText->SetWantsClicks(FALSE);
  208.         someText->SetCanBeGopher(FALSE);    /* Really can't touch    */
  209.         someText->SetFontNumber(systemFont);
  210.         someText->SetFontSize(12);            /* System font size        */
  211.         someText->InsertTextPtr(
  212.             (Ptr) &actionString[1], actionString[0], FALSE);
  213.         someText->InsertTextPtr(
  214.             (Ptr) &objectString[1], objectString[0], FALSE);
  215.         SetModal(TRUE);
  216.         gDecorator->CenterWindow(this);
  217.         Select();
  218. }
  219.  
  220. /*
  221.  * Create the barber pole pane.
  222.  */
  223. void
  224. ProgressPane::IProgressPane(
  225.         CWindow                    *theWindow
  226.     )
  227. {
  228.         inherited::IPane(
  229.             (CView *) theWindow,            /* Enclosure            */
  230.             (CBureaucrat *) theWindow,        /* Supervisor            */
  231.             230,                            /* Width                */
  232.             10,                                /* Height                */
  233.             10,                                /* Horizontal position    */
  234.             65,                                /* Vertical position    */
  235.             sizFIXEDLEFT,                    /* Fixed at the left    */
  236.             sizFIXEDTOP                        /* Fixed from the top    */
  237.         );
  238.         itsPattern = gBarberPolePattern;
  239. }
  240.  
  241. /*
  242.  * Each time we draw the barber pole, we update the pattern.
  243.  */
  244. void
  245. ProgressPane::Draw(
  246.         Rect                    *theRect
  247.     )
  248. {
  249.         LongRect                theAperture;
  250.         Rect                    drawingRect;
  251.         PenState                penState;
  252.         Boolean                    wasLocked;
  253.         short                    temp;
  254.         register short            i;
  255.         register unsigned char    *thePattern;
  256.         
  257.         GetAperture(&theAperture);
  258.         LongToQDRect(&theAperture, &drawingRect);
  259.         GetPenState(&penState);
  260.         PenNormal();
  261.         FrameRect(&drawingRect);
  262.         InsetRect(&drawingRect, 1, 1);
  263.         wasLocked = Lock(TRUE);
  264.         thePattern = itsPattern.aPattern;
  265.         FillRect(&drawingRect, thePattern);
  266.         /*
  267.          * Rotate the pattern.
  268.          */
  269.         temp = thePattern[7];
  270.         for (i = 7; i > 0; --i)
  271.             thePattern[i] = thePattern[i - 1];
  272.         thePattern[0] = temp;
  273.         SetPenState(&penState);
  274.         Lock(wasLocked);
  275. }
  276.  
  277. /*
  278.  * gSIGStatusProc is the default status procedure. It processes events
  279.  * using the "standard" Think C event loop manager. If the global
  280.  * gContinueSigning is FALSE, it exits immediately. Note that
  281.  * Process1Event is wrapped in a failure environment. If you don't
  282.  * do this, TCL will take its default failure action, which is
  283.  * to jump to your event loop. I.e., you'll never return to
  284.  * the Digital Signer manager. This will leave a pending mess
  285.  * in your system that will come back to haunt you, as it did me.
  286.  */
  287. pascal Boolean
  288. gSIGStatusProc(void)
  289. {
  290.         if (gContinueSigning) {
  291.             TRY {
  292.                 gApplication->Process1Event();
  293.             }
  294.             CATCH {
  295.                 NO_PROPAGATE;
  296.             }
  297.             ENDTRY;
  298.         }
  299.         return(gContinueSigning);
  300. }
  301.  
  302.  
  303.